using System;
using System.Buffers;
using System.Collections.Generic;
using M13.Utility;
using UnityEngine;
using UnityEngine.Serialization;

namespace M13.DataStructure//打分：9=>还需优化优化
{
    public static class DataBootSerializer
    {
        static byte[] _result = new byte[6144];
        static ByteReader _byteReader = new ByteReader();

        public static byte[] Serializer(List<ChunkDataBoot> data)
        {
            Array.Clear(_result, 0, _result.Length);
            for (int i = 0; i < data.Count; i++)
            {
                Buffer.BlockCopy(Serializer(data[i]), 0, _result, i * ChunkDataBoot.GetBootLength(), ChunkDataBoot.GetBootLength());
            }
            return _result;
        }
        public static byte[] Serializer(ChunkDataBoot[] data)
        {
            Array.Clear(_result, 0, _result.Length);
            for (int i = 0; i < data.Length; i++)
            {
                Buffer.BlockCopy(Serializer(data[i]), 0, _result, i * ChunkDataBoot.GetBootLength(), ChunkDataBoot.GetBootLength());
            }
            return _result;
        }
        private static byte[] Serializer(ChunkDataBoot data)
        {
            byte[] bootByte = ArrayPool<byte>.Shared.Rent(ChunkDataBoot.GetBootLength());
            Buffer.BlockCopy(BitConverter.GetBytes(data.cvmDataLength), 0, bootByte, 0, BitConverter.GetBytes(data.cvmDataLength).Length);
            Buffer.BlockCopy(BitConverter.GetBytes(data.chmDataLength), 0, bootByte, 4, BitConverter.GetBytes(data.chmDataLength).Length);
            Buffer.BlockCopy(BitConverter.GetBytes(data.ctimDatalength), 0, bootByte, 8, BitConverter.GetBytes(data.ctimDatalength).Length);
            Buffer.BlockCopy(BitConverter.GetBytes(data.dataOffset), 0, bootByte, 12, BitConverter.GetBytes(data.dataOffset).Length);
            Buffer.BlockCopy(BitConverter.GetBytes(data.timeStamp), 0, bootByte, 16, BitConverter.GetBytes(data.timeStamp).Length);
            return bootByte;
        }

        public static List<ChunkDataBoot> Deserializer(byte[] bootBytes)
        {
            if (bootBytes == null || bootBytes.Length != 6144) Debug.LogErrorFormat("传入的数组数据错误:{0}", bootBytes.Length);
            _byteReader.ResetReader();
            List<ChunkDataBoot> list = new List<ChunkDataBoot>();
            for (int i = 0; i < 256; i++)
            {
                ChunkDataBoot chunkDataBoot = new ChunkDataBoot();
                chunkDataBoot.cvmDataLength = _byteReader.ReadInt(bootBytes);
                chunkDataBoot.chmDataLength = _byteReader.ReadInt(bootBytes);
                chunkDataBoot.ctimDatalength = _byteReader.ReadInt(bootBytes);
                chunkDataBoot.dataOffset = _byteReader.ReadInt(bootBytes);
                chunkDataBoot.timeStamp = _byteReader.ReadLong(bootBytes);
                list.Add(chunkDataBoot);
            }

            return list;
        }

        private static ChunkDataBoot Deserialize(byte[] bootByte)
        {
            ChunkDataBoot data;
            data.cvmDataLength = BitConverter.ToInt32(bootByte, 0);
            data.chmDataLength = BitConverter.ToInt32(bootByte, 4);
            data.ctimDatalength = BitConverter.ToInt32(bootByte, 8);
            data.dataOffset = BitConverter.ToInt32(bootByte, 12);
            data.timeStamp = BitConverter.ToInt64(bootByte, 16);
            return data;
        }
    }

    [Serializable]
    public struct ChunkDataBoot
    {
        /// <summary>
        /// 大陆图的一次压缩数据长度
        /// </summary>
        [FormerlySerializedAs("CVM_DataLength")] public int cvmDataLength;
        /// <summary>
        /// 高度图的一次压缩数据长度
        /// </summary>
        [FormerlySerializedAs("CHM_DataLength")] public int chmDataLength;
        /// <summary>
        /// 地皮图的一次压缩数据长度
        /// </summary>
        [FormerlySerializedAs("CTIM_Datalength")] public int ctimDatalength;
        /// <summary>
        /// 区块数据在数据数组中的索引偏移
        /// </summary>
        public int dataOffset;
        /// <summary>
        /// 时间戳
        /// </summary>
        public long timeStamp;

        public ChunkDataBoot(int cvmDataLength, int chmDataLength, int ctimDatalength, int dataOffset, long timeStamp)
        {
            this.cvmDataLength = cvmDataLength;
            this.chmDataLength = chmDataLength;
            this.ctimDatalength = ctimDatalength;
            this.dataOffset = dataOffset;
            this.timeStamp = timeStamp;
        }

        public int GetTotalLength()
        {
            return cvmDataLength + chmDataLength + ctimDatalength;
        }

        public static int GetBootLength()
        {
            return sizeof(int) * 4 + sizeof(long);
        }
    }
}